using System;
using System.Collections;
using System.Data;

using LocalBoard.Domain;

namespace LocalBoard.Persistence.MockAccessor
{
	/// <summary>
	/// Summary description for MockProfileAccessor.
	/// </summary>
	public class MockProfileAccessor : IProfileAccessor, IMockAccessor
	{
		const string anonymousUserId = "Anonymous";
		private int _oId = 0;
		private DataTable _profileTable = new DataTable("Profile");
		public static readonly MockProfileAccessor Instance = 
			new MockProfileAccessor();

		private MockProfileAccessor()
		{
			_profileTable.Columns.Add("Id", typeof(int));
			_profileTable.Columns.Add("UserId", typeof(string));
			_profileTable.Columns.Add("UserName", typeof(string));
			_profileTable.Columns.Add("Password", typeof(string));
			_profileTable.Columns.Add("Email", typeof(string));
			_profileTable.Columns.Add("PhotoPath", typeof(string));
			_profileTable.Columns.Add("CustomInfo", typeof(string));

			Initialize();
		}

		private void Initialize()
		{
			_oId = 0;
			Insert(new Profile("Anonymous", "Unknown", "", ""));
		}

		public void ResetDataTable()
		{
			_profileTable.Clear();
			Initialize();
		}

		public void RemoveRows(int tableIndex, DataRow[] rows)
		{
			throw new NotImplementedException();
		}

		public DataRow[] ExecuteFilter(string filterExpression)
		{
			throw new NotImplementedException();
		}

		#region IProfileAccessor Members

		public ArrayList GetAllUserProfiles()
		{
			ArrayList profileList = new ArrayList();
			foreach(DataRow row in _profileTable.Rows)
			{
				profileList.Add(GetProfileFromResultRow(row));
			}
			return profileList;
		}

		public Profile Get(int id)
		{
			DataRow[] result = _profileTable.Select(string.Format("Id={0}", id));
			if(result.Length > 0)
				return GetProfileFromResultRow(result[0]);
			else
				return null;
		}

		public Profile GetProfileByUserId(string userId)
		{
			DataRow[] result = _profileTable.Select(string.Format("UserId='{0}'", userId));
			if(result.Length > 0)
				return GetProfileFromResultRow(result[0]);
			else
				return null;
		}

		public Profile GetProfileByUserIdAndPassword(string userId, string password)
		{
			DataRow[] result = _profileTable.Select(string.Format("UserId='{0}' and Password='{1}'", userId, password));
			if(result.Length > 0)
				return GetProfileFromResultRow(result[0]);
			else
				return null;
		}

		public Profile GetAnonymousUser()
		{
			Profile anonymous = GetProfileByUserId(anonymousUserId);
			if(anonymous == null)
				this.Insert(new Profile(anonymousUserId, "Unknown", "", ""));
			return GetProfileByUserId(anonymousUserId);
		}

		public int Insert(Profile profile)
		{
			if(GetProfileByUserId(profile.UserId) != null)
				throw new ApplicationException("Duplicate User id");
			_oId++;
			DataRow newRow = _profileTable.NewRow();
			newRow["Id"] = _oId;
			newRow["UserId"] = profile.UserId;
			newRow["UserName"] = profile.UserName;
			newRow["Password"] = profile.Password;
			newRow["Email"] = profile.Email;
			newRow["PhotoPath"] = profile.PhotoPath;
			newRow["CustomInfo"] = profile.CustomInfo;
			_profileTable.Rows.Add(newRow);

			return _oId;
		}

		public void Update(Profile profile)
		{
			DataRow row = FindProfileDataRow(profile.Id);
			if(row!=null)
			{
				row["UserId"] = profile.UserId;
				row["UserName"] = profile.UserName;
				row["Password"] = profile.Password;
				row["Email"] = profile.Email;
				row["PhotoPath"] = profile.PhotoPath;
				row["CustomInfo"] = profile.CustomInfo;
				_profileTable.AcceptChanges();
			}
		}

		public void Delete(int id)
		{
			DataRow row = FindProfileDataRow(id);
			if(row!=null)
			{
				MockClubProfileAccessor.Instance.RemoveRows(0, MockClubProfileAccessor.Instance.ExecuteFilter(string.Format("Profile_Id={0}", id)));
				//TODO: Remove all the related rows in other tables

				_profileTable.Rows.Remove(row);
				_profileTable.AcceptChanges();
			}
		}


		#endregion

		private DataRow FindProfileDataRow(int id)
		{
			foreach(DataRow row in _profileTable.Rows)
			{
				if(DataConverter.GetInteger(row["Id"])==id)
					return row;
			}
			return null;
		}

		private Profile GetProfileFromResultRow(DataRow row)
		{
			MockUserRoleAccessor userRoleAccessor = MockUserRoleAccessor.Instance;
			int profileOId = DataConverter.GetInteger(row["Id"]);

			return new Profile(profileOId, DataConverter.GetString(row["UserId"]), DataConverter.GetString(row["UserName"]),DataConverter.GetString(row["Password"]),DataConverter.GetString(row["Email"]),DataConverter.GetString(row["PhotoPath"]),DataConverter.GetString(row["CustomInfo"]), userRoleAccessor.GetRolesByProfileId(profileOId));
		}

	}
}
